iT邦幫忙

2023 iThome 鐵人賽

DAY 27
0
Modern Web

FastAPI 入門30天系列 第 27

Day-27 檔案上傳

  • 分享至 

  • xImage
  •  

今天我們要介紹如何使用 FastAPI 來建立可以提供檔案上傳的 API 接口。

安裝套件

pip install python-multipart 

由於上傳檔案需要接收表單型態的資料,所以我們要先安裝 python-multipart 套件。

使用 File 類別

File 類別定義用戶端上傳的檔案。

from fastapi import FastAPI, File

app = FastAPI()


@app.post("/files/")
async def create_file(file: bytes = File()):
    return {"file_size": len(file)}

我們在路徑操作函式中定義要傳入一個 bytes 的參數,並指定使用 File,FastAPI 便可以接受使用表單上傳的檔案。

https://ithelp.ithome.com.tw/upload/images/20231002/20152669I2Cqqf2jkK.png

這種方式會將檔案儲存在記憶體中,適用於小型的檔案,但大多數的情況 UploadFile 類別會更好使用。

使用 UploadFile 類別

from fastapi import FastAPI, File, UploadFile

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile):
    return {"filename": file.filename}

與 File 相比,UploadFile 有以下幾個更好的地方:

  • 儲存在記憶體的檔案如果超出上限會將其儲放在硬碟中。
  • 因為不會佔據所有記憶體,這種方法更適合用於影音、圖像、二進位文件等等較大的檔案。
  • 可獲取檔案的 metadata。
  • 自帶 file-like 的 async 接口。
  • 可直接傳遞給其他預期 file-like 類別的套件。

可選的上傳欄位

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile | None = None):
    if not file:
        return "No file uploaded"
    return {"filename": file.filename}

若要將欄位設置為可選的話一樣,一樣類別標註好並設置預設為None即可。

上傳多個文件

@app.post("/uploadfiles/")
async def create_upload_files(files: list[UploadFile]):
    return {"filenames": [file.filename for file in files]}

若要上傳多個檔案,類別可以標註為 UploadFile 類別的 list。

同時傳送其他資料

from fastapi import Form

@app.post("/uploadfile/")
async def create_upload_file(file: UploadFile | None = None, tag: str = Form()):
    if not file:
        return {"filename": "no file", "tag": tag}
    return {"filename": file.filename, "tag": tag}

若要在表單中包含其他資料的話可以使用 Form 類別,這樣可以讓你傳送檔案的時候順便傳送其它所需資料。

小結

今天我們介紹了如何跟使用者接收他們上傳的檔案,我們拿到這些檔案後可以選擇保存在本機或者是又上傳到另一個雲端,例如 AWS S3 或 GCP Cloud Storage 等等。

參考資料

请求文件 - FastAPI (tiangolo.com)
请求表单与文件 - FastAPI (tiangolo.com)


上一篇
Day-26 定時任務與 FastAPI
下一篇
Day-28 容器化
系列文
FastAPI 入門30天30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言